﻿using System;
using System.Collections;
using Common.Utils;
using Game.Kernel;
using Game.Logic.Data;
using Game.Logic.Manager;
using UIFramework;
using NetFramework;
using Sproto;

namespace Game.Logic.Login
{
    public class GameLoadingModelEvent : GameModelEvent
    {
        private GameStatus m_status = GameStatus.Invalid;
        public GameStatus Status { get => m_status; private set => m_status = value; }
        public float Progress { get; private set; }

        GameLoadingModelEvent(GameStatus _status, GameDataType _dataType, GameBaseData _gameData) : base(_dataType, _gameData)
        {
            Status = _status;
            Progress = 0.0f;
        }

        public static GameLoadingModelEvent Create(GameStatus _status, GameDataType _dataType, GameBaseData _gameData)
        {
            return new GameLoadingModelEvent(_status, _dataType, _gameData);
        }

        public static GameLoadingModelEvent Create(GameStatus _status, GameDataType _dataType, GameBaseData _gameData, float _progress)
        {
            GameLoadingModelEvent modelEvent = new GameLoadingModelEvent(_status, _dataType, _gameData);
            modelEvent.Progress = _progress;
            return modelEvent;
        }
    }

    public class GameLoadingModel : GameUIModel
    {
        private GameStatus m_status = GameStatus.Invalid;
        public GameStatus Status { get => m_status; protected set => m_status = value; }

        private GameVersionData m_versionData;
        public GameServerData GameServerData { private set; get; }

        GameLoadingModel()
        {
            m_versionData = RegisterDataEventHandler<GameVersionData>(GameDataType.GameVersion, OnGameDataUpdate);
            InitGameLoadingStatus();
        }

        #region Game Data Handler Interface
        private void OnGameDataUpdate(GameBaseData _data)
        {
            DispatchVersionData();
        }
        #endregion

        #region GameStatus Interface
        private void InitGameLoadingStatus()
        {
            Status = ClientKernel.Instance.GameController.GameStatus;
            ClientKernel.Instance.GameController.RegisterGameStatusUpdateHanler(OnUpdateGameStatus);
        }


        public virtual void OnUpdateGameStatus(GameStatus _cur, GameStatus _pre)
        {
            Status = _cur;
            switch(Status)
            {
                case GameStatus.Downloading:
                    DownloadResult result = GameVersionManager.Instance.GetCurDownloadResult();
                    if (null != result)
                        CoroutineController.Instance.StartCoroutine(UpdateGameDownloading(result));
                    break;
                default:
                    break;
            }
            // DispatchVersionData();
        }
        #endregion


        #region Model Event Interface
        public IEnumerator UpdateGameDownloading(DownloadResult _result)
        {
            while (!_result.IsDone)
            {
                base.DispatchModelEvent(GameLoadingModelEvent.Create(Status, GameDataType.GameVersion, m_versionData, _result.Progress));
                yield return null;
            }
            base.DispatchModelEvent(GameLoadingModelEvent.Create(Status, GameDataType.GameVersion, m_versionData, _result.Progress));
            yield return null;
        }

        private void DispatchVersionData()
        {
            base.DispatchModelEvent(GameLoadingModelEvent.Create(Status, GameDataType.GameVersion, m_versionData));
        }

        protected override void OnLinkView()
        {
            DispatchVersionData();
        }

        protected override void OnUnlinkView()
        {

        }
        #endregion
    }
}
